package com.voip.sipphone;


import com.voip.Invite.RtpTransmitter;
import com.voip.Invite.SipCall;

import javax.media.rtp.InvalidSessionAddressException;
import javax.media.rtp.SessionAddress;
import javax.sdp.*;
import javax.sip.*;
import javax.sip.address.SipURI;
import javax.sip.header.*;
import javax.sip.message.Message;
import javax.sip.message.Request;
import javax.sip.message.Response;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Vector;

/**
 * Created by RXJ on 2018/1/19.
 */
public class Invite extends SipCall {

    int localMediaPort;

    String remoteHost = null;

    public static RtpTransmitter transmitter;

    public Invite(){
        localMediaPort = -1;

        try {
            DatagramSocket socket = new DatagramSocket();
            localMediaPort = socket.getLocalPort();
            socket.close();
            initRTP(localMediaPort);
        } catch (Exception e1) {
            System.out.println(e1);
        }
    }

    public static void  processInviteResponse(ResponseEvent responseReceivedEvent) throws SipException, InvalidArgumentException, ParseException, SdpException, InvalidSessionAddressException, IOException {
        Response response = (Response) responseReceivedEvent.getResponse();
        ClientTransaction tid = responseReceivedEvent.getClientTransaction();

        CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
       // Dialog dialog = tid.getDialog();
        if (response.getStatusCode() == Response.OK) {
            System.out.println("Dialog after 200 OK  " );
            System.out.println("Dialog State after 200 OK  ");
            System.out.println("Sending ACK");
            if (tid != null) {
                Request ack = (Request) tid.getDialog()
                        .createRequest(Request.ACK);
                tid.getDialog().sendAck(ack);
            }else{
                sendAck(response);
                //startConversation(response, tid);
            }


        }
        if (response.getStatusCode() == Response.TRYING) {
            System.out.println("Dialog after 100 TRYING  "  );
            System.out.println("Dialog State after 100 TRYING  ");
            /*
            if (tid != null) {
                Request ack = (Request) tid.getDialog()
                        .createRequest(Request.ACK);
                tid.getDialog().sendAck(ack);
            }
            */
        }
    }



    private static void sendAck(Response response) throws SipException, ParseException, InvalidArgumentException {
        SipURI requestURI = SipLayer.listener.addressFactory.createSipURI(
                SipLayer.listener.getUsername(), Register.address);

        ArrayList<ViaHeader> viaHeaders = new ArrayList<>();
        //创建 viaHeaders 根据 response 中获取
        ViaHeader viaHeader = (ViaHeader) response.getHeader("Via");

        viaHeaders.add(viaHeader);

        CallIdHeader callIdHeader = (CallIdHeader) response.getHeader("Call-ID");

        FromHeader fromHeader = (FromHeader) response.getHeader("From");

        ToHeader toHeader = (ToHeader) response.getHeader("To");

        CSeqHeader cSeqHeader = SipLayer.listener.headerFactory.createCSeqHeader(1L, Request.ACK);

        //创建  Max_forwards 默认：70
        MaxForwardsHeader maxForwards = SipLayer.listener.headerFactory.createMaxForwardsHeader(70);


        Request ackRequest = SipLayer.listener.sipFactory.createMessageFactory()
                .createRequest(
                        requestURI,
                        Request.ACK,
                        callIdHeader,
                        cSeqHeader,
                        fromHeader,
                        toHeader,
                        viaHeaders,
                        maxForwards
                        );

        /*SipLayer.listener.clientTransaction =
                SipLayer.listener.sipProvider.getNewClientTransaction(ackRequest);
        SipLayer.listener.clientTransaction.sendRequest();*/

        SipLayer.listener.sipProvider.sendRequest(ackRequest);

    }

    private  void startConversation(Message response,
                                          Transaction clientTransaction) throws SdpException, IOException, InvalidSessionAddressException {
        System.out.println("Starting conversation");

        String sdpData = new String(response.getRawContent());
        SdpFactory sdpFactory = SdpFactory.getInstance();
        SessionDescription sessionDescription = sdpFactory
                .createSessionDescription(sdpData);
        Vector mediaDescriptions = sessionDescription
                .getMediaDescriptions(true);

        for (int mdNum = 0; mdNum < mediaDescriptions.size(); mdNum++) {
            MediaDescription mediaDescription = (MediaDescription) mediaDescriptions
                    .elementAt(mdNum);
            Media media = mediaDescription.getMedia();
            String proto = media.getProtocol();
            String type = media.getMediaType();
            int port = media.getMediaPort();

            Vector formats = media.getMediaFormats(true);

            if (formats.size() < 1) {

            }
            int sdpFormat = SdpConstants.PCMU;
            try {
                sdpFormat = Integer.parseInt((String) formats.elementAt(0));
            } catch (NumberFormatException nfExc) {
                nfExc.printStackTrace();
            }

            transmitter = new RtpTransmitter(SipPhone.ipAddr, port, sdpFormat);

            startReceiver(SipPhone.ipAddr, SipPhone.ipAddr_port);

            transmitter = new RtpTransmitter(SipPhone.ipAddr, SipPhone.ipAddr_port, sdpFormat);
        }

        }

    private  void startReceiver(String remoteHost, int localPort)
            throws InvalidSessionAddressException, IOException{
               SessionAddress remoteAddress = new SessionAddress(InetAddress
                .getByName(remoteHost), localPort);
            //rtpManager.addTarget(remoteAddress);
    }
}
